/* Gyroe 1.0.0 */
/* misc.c : Miscellaneous routines. Important one is compress, which is used to
   compress objects before sending them through the last machine call in backend.c */

#include "euphoria.h"
#include "main-.h"

int _3upper(int x)
{
    int _186, _188;

    if (IS_ATOM_INT(x)) {
        _186 = (x >= 97);
        _188 = (x <= 122);
    }
    else {
        _186 = binary_op(GREATEREQ, x, 97);
        _188 = binary_op(LESSEQ, x, 122);
    }

    if (IS_ATOM_INT(_186) && IS_ATOM_INT(_188)) {
        _188 = (_186 != 0 && _188 != 0);
    }
    else {
        _188 = binary_op(AND, _186, _188);
    }

    if (IS_ATOM_INT(_188)) {
        if (_188 == (short)_188)
            _188 = _188 * 32;
        else
            _188 = NewDouble(_188 * (double)32);
    }
    else {
        _188 = binary_op(MULTIPLY, _188, 32);
    }

    if (IS_ATOM_INT(x) && IS_ATOM_INT(_188)) {
        _188 = x - _188;
        if (_188 + HIGH_BITS >= 0)
            _188 = NewDouble((double)_188);
    }
    else {
        _188 = binary_op(MINUS, x, _188);
    }

    return _188;
}

int _7allocate(int n)
{
    return machine(16, n);
}

int _7int_to_bytes(int x)
{
    int a, b, c, d;
    int _1, _2;

    // a = remainder(x, #100)
    if (IS_ATOM_INT(x)) {
        a = (x % 256);
    }
    else {
        temp_d.dbl = (double)256;
        a = Dremainder(DBL_PTR(x), &temp_d);
    }

    if (IS_ATOM_INT(x)) {
        if (x >= 0) {
            x = x / 256;
        }
        else {
            temp_dbl = floor((double)x / (double)256);
            if (x != MININT)
                x = (long)temp_dbl;
            else
                x = NewDouble(temp_dbl);
        }
    }
    else {
        _2 = binary_op(DIVIDE, x, 256);
        x = unary_op(FLOOR, _2);
        DeRef(_2);
    }

    if (IS_ATOM_INT(x)) {
        b = (x % 256);
    }
    else {
        temp_d.dbl = (double)256;
        b = Dremainder(DBL_PTR(x), &temp_d);
    }

    if (IS_ATOM_INT(x)) {
        if (x >= 0) {
            x = x / 256;
        }
        else {
            temp_dbl = floor((double)x / (double)256);
            if (x != MININT)
                x = (long)temp_dbl;
            else
                x = NewDouble(temp_dbl);
        }
    }
    else {
        _2 = binary_op(DIVIDE, x, 256);
        x = unary_op(FLOOR, _2);
        DeRef(_2);
    }

    if (IS_ATOM_INT(x)) {
        c = (x % 256);
    }
    else {
        temp_d.dbl = (double)256;
        c = Dremainder(DBL_PTR(x), &temp_d);
    }

    if (IS_ATOM_INT(x)) {
        if (x >= 0) {
            x = x / 256;
        }
        else {
            temp_dbl = floor((double)x / (double)256);
            if (x != MININT)
                x = (long)temp_dbl;
            else
                x = NewDouble(temp_dbl);
        }
    }
    else {
        _2 = binary_op(DIVIDE, x, 256);
        x = unary_op(FLOOR, _2);
        DeRef(_2);
    }

    if (IS_ATOM_INT(x)) {
        d = (x % 256);
    }
    else {
        temp_d.dbl = (double)256;
        d = Dremainder(DBL_PTR(x), &temp_d);
    }

    _1 = NewS1(4);
    _2 = (int)((s1_ptr)_1)->base;
    *((int *)(_2+4)) = a;
    *((int *)(_2+8)) = b;
    *((int *)(_2+12)) = c;
    *((int *)(_2+16)) = d;
    DeRef(x);
    return MAKE_SEQ(_1);
}

int _7atom_to_float64(int a)
{
    return machine(46, a);
}

int _7atom_to_float32(int a)
{
    return machine(48, a);
}

int _7float32_to_atom(int ieee32)
{
    return machine(49, ieee32);
}

int _12dir(int name)
{
    return machine(22, name);
}

int _16compress(int x)
{
    int s = 0, x4 = 0;
    int _3952 = 0, _3955 = 0, _3973 = 0;
    int _1, _2;
    int i;

    if (IS_ATOM_INT(x)) {
        // if x >= MIN1B and x <= MAX1B then
        if (x >= -2 && x <= 246) {
            _3955 = NewDouble((double)(x - -2));
            _1 = NewS1(1);
            _2 = (int)((s1_ptr)_1)->base;
            Ref(_3955);
            *((int *)(_2+4)) = _3955;
            _3955 = MAKE_SEQ(_1);
            DeRef(x);
            DeRefi(x4);
            DeRef(s);
            DeRef(_3973);
            DeRef(_3952);
            return _3955;
        }
        else if (x >= _16MIN2B && x <= 32767) {
            x = x - _16MIN2B;
            _3952 = x & 255;
            _3955 = x / 256;
            _1 = NewS1(3);
            _2 = (int)((s1_ptr)_1)->base;
            *((int *)(_2+4)) = 249;
            Ref(_3952);
            *((int *)(_2+8)) = _3952;
            Ref(_3955);
            *((int *)(_2+12)) = _3955;
            _3955 = MAKE_SEQ(_1);
            DeRef(x);
            DeRefi(x4);
            DeRef(s);
            DeRef(_3973);
            DeRef(_3952);
            return _3955;
        }
        else if (x >= _16MIN3B && x<= _16MAX3B) {
            x = x - _16MIN3B;
            _1 = NewS1(4);
            _2 = (int)((s1_ptr)_1)->base;
            *((int *)(_2+4)) = 250;
            *((int *)(_2+8)) = x & 255;
            *((int *)(_2+12)) = (x / 256) & 255;
            *((int *)(_2+16)) = x / 65536;
            DeRef(x);
            DeRefi(x4);
            DeRef(s);
            return MAKE_SEQ(_1);
        }
        else {
            // return I4B & int_to_bytes(x-MIN4B)
            DeRef(_3973);
            if (IS_ATOM_INT(x) && IS_ATOM_INT(_16MIN4B)) {
                _3973 = x - _16MIN4B;
                if (_3973 + HIGH_BITS >= 0)
                    _3973 = NewDouble((double)_3973);
            }
            else {
                _3973 = binary_op(MINUS, x, _16MIN4B);
            }
            Ref(_3973);
            _3973 = _7int_to_bytes(_3973);
            Prepend(&_3973, _3973, 251);
            DeRef(x);
            DeRefi(x4);
            DeRef(s);
            DeRef(_3955);
            DeRef(_3952);
            return _3973;
        }
    }

    if (IS_ATOM(x)) {
        if (x == _7float32_to_atom(_7atom_to_float32(x))) {
            // return F4B & x4
            Prepend(&_3973, x4, 252);
            DeRef(x);
            DeRefDSi(x4);
            DeRef(s);
            DeRef(_3955);
            DeRef(_3952);
            return _3973;
        }
        else {
            // return F8B & atom_to_float64(x)
            Ref(x);
            _3973 = _7atom_to_float64(x);
            Prepend(&_3973, _3973, 253);
            DeRef(x);
            DeRefi(x4);
            DeRef(s);
            DeRef(_3955);
            DeRef(_3952);
            return _3973;
        }
    }

    if (SEQ_PTR(x)->length <= 255) {
        // s = {S1B, length(x)}
        _3973 = SEQ_PTR(x)->length;
        DeRef(s);
        _1 = NewS1(2);
        _2 = (int)((s1_ptr)_1)->base;
        ((int *)_2)[1] = 254;
        ((int *)_2)[2] = _3973;
        s = MAKE_SEQ(_1);
    }
    else {
        // s = S4B & int_to_bytes(length(x))
        DeRef(_3973);
        _3973 = SEQ_PTR(x)->length;
        _3973 = _7int_to_bytes(_3973);
        Prepend(&s, _3973, 255);
    }

    /* Sequence? Just compress all parts of it recursively. */
    for (i = 1; i <= SEQ_PTR(x)->length;i++) {
        // s &= compress(x[i])
        DeRef(_3955);
        _2 = (int)SEQ_PTR(x);
        _3955 = (int)*(((s1_ptr)_2)->base + i);
        Ref(_3955);
        Ref(_3955);
        _3955 = _16compress(_3955);
        Concat((object_ptr)&s, s, (s1_ptr)_3955);
    }

    DeRef(x);
    DeRefi(x4);
    DeRef(_3955);
    DeRef(_3973);
    DeRef(_3952);
    return s;
}

/* I'll fix paths later, since I want to overhaul how they're done anyway. */
int _20e_path_open(int _name, int _mode)
{
    int p, src_file;
    int full_name = 0, path = 0;
    int _4482 = 0;
    int _4485;
    int _2;

    //     src_file = open(name, mode)
    src_file = EOpen(_name, _mode);

    //     if src_file != -1 then
    if (src_file == -1)
        goto L1;

    // 	return src_file
    DeRefDS(_name);
    DeRefDSi(_mode);
    return src_file;
L1:

    //     for i = 1 to length(SLASH_CHARS) do
    DeRef(_4482);
    _4482 = SEQ_PTR(_4SLASH_CHARS)->length;
    { int i;
        i = 1;
L2:
        if (i > _4482)
            goto L3;

        // 	if find(SLASH_CHARS[i], name) then
        _2 = (int)SEQ_PTR(_4SLASH_CHARS);
        _4485 = (int)*(((s1_ptr)_2)->base + i);
        _4485 = find(_4485, _name);
        if (_4485 == 0)
            goto L4;

        // 	    return -1
        DeRefDS(_name);
        DeRefDSi(_mode);
        DeRefi(path);
        DeRefi(full_name);
        DeRef(_4482);
        return -1;
L4:

        //     end for
        i = i + 1;
        goto L2;
L3:
        ;
    }

    //     path = getenv("PATH")
    DeRefi(path);
    path = EGetEnv(_4487);

    //     if atom(path) then
    _4485 = IS_ATOM(path);
    if (_4485 == 0)
        goto L5;

    // 	return -1
    DeRefDS(_name);
    DeRefDSi(_mode);
    DeRefi(path);
    DeRefi(full_name);
    DeRef(_4482);
    return -1;
L5:

    //     full_name = ""
    RefDS(_39);
    DeRefi(full_name);
    full_name = _39;

    //     p = 1
    p = 1;

    //     path &= PATH_SEPARATOR -- add end marker
    if (IS_SEQUENCE(path) && IS_ATOM(_4PATH_SEPARATOR)) {
        Append(&path, path, _4PATH_SEPARATOR);
    }
    else if (IS_ATOM(path) && IS_SEQUENCE(_4PATH_SEPARATOR)) {
    }
    else {
        Concat((object_ptr)&path, path, (s1_ptr)_4PATH_SEPARATOR);
    }

    //     while p <= length(path) do
L6:
    _4485 = SEQ_PTR(path)->length;
    if (p > _4485)
        goto L7;

    // 	if (length(full_name) = 0 and path[p] = ' ') or path[p] = '\t' then
    _4485 = SEQ_PTR(full_name)->length;
    _4485 = (_4485 == 0);
    if (_4485 == 0) {
        _4485 = 0;
        goto L8;
    }
    DeRef(_4482);
    _2 = (int)SEQ_PTR(path);
    _4482 = (int)*(((s1_ptr)_2)->base + p);
    _4482 = (_4482 == 32);
    _4485 = (_4482 != 0);
L8:
    if (_4485 != 0) {
        goto L9;
    }
    _2 = (int)SEQ_PTR(path);
    _4485 = (int)*(((s1_ptr)_2)->base + p);
    _4485 = (_4485 == 9);
LA:
    if (_4485 == 0)
        goto LB;
LC:
    goto L9;
LB:

    // 	elsif path[p] = PATH_SEPARATOR then
    _2 = (int)SEQ_PTR(path);
    _4485 = (int)*(((s1_ptr)_2)->base + p);
    if (_4485 != _4PATH_SEPARATOR)
        goto LD;

    // 	    if length(full_name) then
    _4485 = SEQ_PTR(full_name)->length;
    if (_4485 == 0)
        goto L9;

    // 		while length(full_name) and full_name[$] = ' ' do
LE:
    _4485 = SEQ_PTR(full_name)->length;
    if (_4485 == 0) {
        goto LF;
    }
    DeRef(_4482);
    _4482 = SEQ_PTR(full_name)->length;
    _2 = (int)SEQ_PTR(full_name);
    _4482 = (int)*(((s1_ptr)_2)->base + _4482);
    _4482 = (_4482 == 32);
L10:
    if (_4482 == 0)
        goto LF;

    // 		    full_name = full_name[1..$-1]
    DeRef(_4482);
    _4482 = SEQ_PTR(full_name)->length;
    _4482 = _4482 - 1;
    rhs_slice_target = (object_ptr)&full_name;
    RHS_Slice((s1_ptr)full_name, 1, _4482);

    // 		end while
    goto LE;
LF:

    // 		src_file = open(full_name & SLASH & name, mode)
    {
        int concat_list[3];

        concat_list[0] = _name;
        concat_list[1] = _4SLASH;
        concat_list[2] = full_name;
        Concat_N((object_ptr)&_4482, concat_list, 3);
    }
    src_file = EOpen(_4482, _mode);

    // 		if src_file != -1 then
    if (src_file == -1)
        goto L11;

    // 		    file_name[1] = full_name & SLASH & name
    {
        int concat_list[3];

        concat_list[0] = _name;
        concat_list[1] = _4SLASH;
        concat_list[2] = full_name;
        Concat_N((object_ptr)&_4482, concat_list, 3);
    }
    RefDS(_4482);
    _2 = (int)SEQ_PTR(_4file_name);
    if (!UNIQUE(_2)) {
        _2 = (int)SequenceCopy((s1_ptr)_2);
        _4file_name = MAKE_SEQ(_2);
    }
    _2 = (int)(((s1_ptr)_2)->base + 1);
    *(int *)_2 = _4482;

    // 		    return src_file
    DeRefDS(_name);
    DeRefDSi(_mode);
    DeRefi(path);
    DeRefDSi(full_name);
    DeRefDS(_4482);
    return src_file;
    goto L9;
L11:

    // 		    full_name = ""
    RefDS(_39);
    DeRefi(full_name);
    full_name = _39;
L12:
L13:
    goto L9;
LD:

    // 	    full_name &= path[p] -- build up the directory name
    DeRef(_4482);
    _2 = (int)SEQ_PTR(path);
    _4482 = (int)*(((s1_ptr)_2)->base + p);
    Append(&full_name, full_name, _4482);
L9:

    // 	p += 1
    p = p + 1;

    //     end while
    goto L6;
L7:

    //     return -1
    DeRefDS(_name);
    DeRefDSi(_mode);
    DeRefi(path);
    DeRefi(full_name);
    DeRef(_4482);
    return -1;
    ;
}

